home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / lptalk-1.3 / macro.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  5KB  |  209 lines

  1. /************************************************************************/
  2. /* LP-Talk
  3.     Version 1.0 [ 9/24/90]
  4.     Version 1.1 [ 9/27/90]
  5.     Version 1.2 [ 9/28/90]
  6. */
  7. /* TinyTalk macro handling.                        */
  8. /*                                    */
  9. /*    Version 1.0 [ 1/25/90] : Initial implementation by ABR.        */
  10. /*        1.1 [ 1/26/90] : Added support for listing macros.    */
  11. /*        1.2 [ 1/27/90] : Fixed bug in add_macro.        */
  12. /*        1.3 [ 2/ 5/90] : Fixed error message in remove_macro.    */
  13. /*                                    */
  14. /************************************************************************/
  15.  
  16. #include "tl.h"
  17. #include <stdio.h>
  18.  
  19. #define MAX_ARGS 4            /* Watch out in process_macro */
  20.                     /* if you change this. */
  21.  
  22. #define NAME_LEN 31            /* Size of a macro's name */
  23. typedef char namestr[NAME_LEN+1];    /* Also max arg size; if changed, */
  24.                     /* look at process_macro. */
  25.  
  26. typedef struct macro {
  27.   struct macro *next, *prev;        /* Linked list of macros */
  28.   namestr the_name;
  29.   char *the_body;            /* Dynamically allocated */
  30. } macro;
  31.  
  32. extern char *malloc();
  33.  
  34. macro *find_macro();
  35.  
  36. static macro *header;
  37.  
  38. init_macros()
  39. {
  40.   header = NULL;
  41. }
  42.  
  43. add_macro(name, body)
  44.   register char *name;
  45.   char *body;
  46. {
  47.   register macro *new;
  48.  
  49.   if (strlen(name) > NAME_LEN)        /* Silently truncate long names */
  50.     name[NAME_LEN] = '\0';
  51.  
  52.   if (find_macro(name) != NULL) {
  53.     fprintf(stderr, "%% Macro %s is already defined.\n", name);
  54.     return;
  55.   }
  56.  
  57.   new = (macro *) malloc(sizeof(struct macro));    /* Allocate space */
  58.   new->prev = NULL;            /* Add at front of list */
  59.   new->next = header;
  60.   if (new->next != NULL)        /* If not at tail of list, */
  61.     new->next->prev = new;        /* Set up backlink. */
  62.   header = new;
  63.  
  64.   strcpy(new->the_name, name);
  65.   new->the_body = malloc(strlen(body) + 1);
  66.   strcpy(new->the_body, body);
  67. }
  68.  
  69. remove_macro(name)            /* Undefine a macro */
  70.   register char *name;
  71. {
  72.   register macro *where;
  73.  
  74.   if (strlen(name) > NAME_LEN)        /* Silently truncate long names */
  75.     name[NAME_LEN] = '\0';
  76.  
  77.   where = find_macro(name);
  78.   if (where == NULL) {
  79.     fprintf(stderr, "%% Macro %s was not defined.\n", name);
  80.     return;
  81.   }
  82.  
  83.   if (where->prev == NULL)        /* Unlink from head */
  84.     header = where->next;
  85.   else
  86.     where->prev->next = where->next;
  87.  
  88.   if (where->next != NULL)        /* If not at end, fix back link */
  89.     where->next->prev = where->prev;
  90.  
  91.   free(where->the_body);        /* Free allocated storage. */
  92.   free(where);
  93. }
  94.  
  95. write_macros(name)            /* Write macros to a file. */
  96.   char *name;
  97. {
  98.   register FILE *macro_file;
  99.   register macro *where;
  100.  
  101.   expand_filename(name);
  102.   macro_file = fopen(name, "w");    /* Open file */
  103.   if (macro_file == NULL) {
  104.     fprintf(stderr,"%% Could not write macros to %s .\n", name);
  105.     return;
  106.   }
  107.  
  108.   where = header;
  109.   while (where != NULL) {        /* Scan linked list, outputting */
  110.     fputs("/def ", macro_file);        /* the macros. */
  111.     fputs(where->the_name, macro_file);
  112.     fputs(" = ", macro_file);
  113.     fputs(where->the_body, macro_file);
  114.     fputc('\n', macro_file);
  115.     where = where->next;
  116.   }
  117.  
  118.   fclose(macro_file);
  119. }
  120.  
  121. process_macro(name, args, deststr)    /* Process a macro invocation. */
  122.   char *name, *args, *deststr;        /* Warning: no length checking! */
  123. {
  124.   register macro *where;
  125.   register char *source, *dest, ch;
  126.   namestr arg_ary[MAX_ARGS];
  127.   int i;
  128.  
  129.   if (strlen(name) > NAME_LEN)        /* Silently truncate long names */
  130.     name[NAME_LEN] = '\0';
  131.  
  132.   where = find_macro(name);
  133.   if (where == NULL) {
  134.     fprintf(stderr,"%% Macro %s is not defined.\n", name);
  135.     deststr[0] = '\0';
  136.     return;
  137.   }
  138.  
  139.   for (i=0; i<MAX_ARGS; i++)        /* Zero all arguments. */
  140.     arg_ary[i][0] = '\0';
  141.  
  142.   sscanf(args, "%31s %31s %31s %31s", arg_ary[0], arg_ary[1], arg_ary[2],
  143.      arg_ary[3]);
  144.  
  145.   source = where->the_body;        /* Start copying macro text. */
  146.   dest = deststr;
  147.  
  148.   while (*source != '\0') {
  149.     if (*source != '%')            /* If not special char, just copy. */
  150.       *dest++ = *source++;
  151.     else {                /* Look at next char. */
  152.       source++;
  153.       ch = *source;
  154.  
  155.       if ((ch == '\\') || (ch == ';')) { /* Backslash or ";" ==> newline. */
  156.     *dest++ = '\n';
  157.     source++;
  158.       }
  159.       else if (ch == '%') {        /* Double % ==> single %. */
  160.     *dest++ = '%';
  161.     source++;
  162.       }
  163.       else if (ch == '*') {        /* Entire command line. */
  164.     strcpy(dest, args);
  165.     dest += strlen(args);
  166.     source++;
  167.       }
  168.       else if ((ch >= '1') && (ch <= '4')) { /* Argument insertion. */
  169.     strcpy(dest, arg_ary[ch - '1']);
  170.     dest += strlen(arg_ary[ch - '1']);
  171.     source++;
  172.       }
  173.       else {                /* Don't know what it was.  Guess %. */
  174.     *dest++ = '%';            /* Don't advance source here. */
  175.       }
  176.     }
  177.   }
  178.  
  179.   *dest++ = '\n';            /* Add a newline. */
  180.   *dest = '\0';                /* Terminate the expansion. */
  181. }
  182.  
  183. macro *find_macro(name)
  184.   register char *name;
  185. {
  186.   register macro *where;
  187.  
  188.   where = header;
  189.   while ((where != NULL) && (!equalstr(where->the_name, name)))
  190.     where = where->next;
  191.  
  192.   return (where);
  193. }
  194.  
  195. list_all_macros(full)
  196.   int full;
  197. {
  198.   register macro *where;
  199.  
  200.   where = header;
  201.   while (where != NULL) {
  202.     if (full)
  203.       printf("%% %s = %s\n", where->the_name, where->the_body);
  204.     else
  205.       printf("%% %s\n", where->the_name);
  206.     where = where->next;
  207.   }
  208. }
  209.